import json

from flask import Blueprint
from flask import request

from core.decorate import progress
from core.tools import get_model_struct

api = Blueprint('api', __name__, url_prefix='/api')


@api.route('/proxy_state')
def proxy_state():
    from core.documents import AskProxySetting
    state = AskProxySetting.get_state()
    result = [{'content': '记录请求', 'goal_state': 'listenAsk'},
              {'content': '代理去重--请求参数', 'goal_state': 'use_data'},
              {'content': '代理去重--返回结果', 'goal_state': 'use_result'},
              {'content': '代理去重--请求头', 'goal_state': 'use_header'}]
    for i, goal_state in enumerate(['listenAsk', 'use_data', 'use_result', 'use_header']):
        result[i]['status'] = '开启' if state[goal_state] else '关闭'
    return json.dumps(result, ensure_ascii=False)


@api.route('/change_status')
def change_status():
    goal_state = request.values['goal_state']
    from core.documents import AskProxySetting
    state = AskProxySetting.get_state()
    state[goal_state] = not state[goal_state]
    state.save()
    return '开启' if state[goal_state] else '关闭'


@api.route('/get_urls')
def get_urls():
    urls = get_model_struct()
    for k1 in urls:
        for k2 in urls[k1]:
            res = urls[k1][k2]
            urls[k1][k2] = [str(r) for r in res]
    return json.dumps(urls, ensure_ascii=False)


@api.route('/search')
def search():
    from core.documents import APIModel
    from itertools import chain
    query_content = request.values['query_content']
    res = [model.relate_url for model in set(
        chain(APIModel.objects(url__icontains=query_content), APIModel.objects(comment__icontains=query_content)))]
    return json.dumps(res)


@api.route('/progress')
def get_progress():
    from core.documents import TaskProgress
    key = request.values['key']
    task = TaskProgress.objects(key=key).first()
    return json.dumps(task.rate)


@api.route('/progress/all')
def get_all_progress():
    from core.documents import TaskProgress
    res = {}
    for task in TaskProgress.objects():
        res[task.name] = [task.rate, task.key]
    for task in TaskProgress.objects():
        if task.rate == 100:
            task.delete()
    return json.dumps(res)


@api.route('/rebuild/doc_one/<path:relate_url>')
@progress('重新构建一个模型')
def rebuild_doc_one(relate_url):
    from core.documents import APIModel
    from core.build_model import build_one_process
    model = APIModel.objects(relate_url=relate_url).first()
    url = model.url
    APIModel.objects(relate_url=relate_url).delete()
    yield from build_one_process(url)


@api.route('/clean/model')
def clean_model():
    from core.documents import APIModel, RawValue
    APIModel.drop_collection()
    RawValue.drop_collection()
    return json.dumps(True)


@api.route('/build/model')
@progress('批量归纳模型')
def build_model():
    from core.documents import Ask, TaskProgress
    from core.build_model import build_one_process
    checked = set()
    count = Ask.objects().count()
    index = 0
    for ask in Ask.objects():
        index += 1
        if not ask.url:
            continue
        if ask.url in checked:
            continue
        checked.add(ask.url)
        task = TaskProgress(key=ask.url, name=ask.url, count=100)
        task.save()
        for i in build_one_process(ask.url):
            task.rate = i
        task.finish()
        yield int(index * 100 / count)
    yield 100


@api.route('/update/model')
@progress('更新模型')
def update_model():
    from core.documents import Question
    count = Question.objects(solved=True).count()
    index = 0
    for ans in Question.objects(solved=True):
        index += 1
        ans.update_model()
        yield int(index / count * 100)


@api.route('/ask/count')
def ask_count():
    from core.documents import Ask
    return json.dumps(Ask.objects().count())


@api.route("/ask/clean")
def ask_clean():
    count = int(request.values['count'])
    from core.documents import Ask
    over_count = {}
    for ask in Ask.objects().order_by('-date'):
        if ask.url not in over_count:
            over_count[ask.url] = 0
        over_count[ask.url] += 1
        if over_count[ask.url] > count:
            ask.delete()
    return json.dumps(Ask.objects().count())
